#ifndef _REGIONITEM_H
#define _REGIONITEM_H

#include <QGraphicsItem>

typedef enum 
{
	RegionTypeBegin = QGraphicsItem::UserType + 1,
	RectangleType = RegionTypeBegin,
	EllipseType,
	RectangleRingType,
	EllipseRingType,
	PolygonType,
	RegionTypeEnd,
	GroupType,
}RegionType;

class RegionAnchor;
class RegionScene;	
class RegionGroup;
class RegionPrivate;
class Region : public QGraphicsItem
{
	Q_INTERFACES(QGraphicsItem)	
public:
	Region(Region *parent = 0);
	Region(const Region& other);
	virtual ~Region();	
public:
	QString regionUuid() const;
	void setRegionUuid(const QString&);	
	bool isMovable() const;
	void setMovable(const bool);
	bool isAdjustable() const;
	void setAdjustable(const bool);
	bool isSelectable() const;
	void setSelectable(const bool);
	bool isFocusable() const;
	void setFocusable(const bool);
public:
	static int borderWidth();
	static void setBorderWidth(const int);
	static  QColor borderColor();
	static void setBorderColor(const QColor&);
	static QColor anchorColor();
	static void setAnchorColor(const QColor&);
	static QSizeF anchorSize();
	static void setAnchorSize(const QSizeF&);
	static Qt::KeyboardModifiers modifiers();
	static void setModifiers(const Qt::KeyboardModifiers);	
	static Region* createRegion(const int type);
public:
	Region* parentRegion() const;
	void setParentRegion(Region*);
	RegionGroup* regionGroup() const;
	void setRegionGroup(RegionGroup*);
	QList<Region*> childregionItems() const;
	RegionScene* regionScene() const;
public:
	virtual Region* clone() const = 0;
	virtual QDataStream& operator<<(QDataStream&) const;
	virtual QDataStream& operator>>(QDataStream&);		
	virtual QPainterPath shape() const;
	virtual QRectF boundingRect() const;
	virtual QRectF selectedRect() const;
	virtual QSizeF rectangleSize() const;
	virtual void setRectangleSize(const QSizeF&);
	virtual void paint(QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget = 0);	
	inline void moveBy(const QPointF& d) { QGraphicsItem::moveBy(d.x(), d.y());}
protected:
	Region(RegionPrivate &dd, 
		Region *parent = 0, 
		RegionScene* scene = 0);
	QScopedPointer<RegionPrivate> d_ptr;	
	virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *);
	virtual void mousePressEvent(QGraphicsSceneMouseEvent *);
	virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *);
private:
	Q_DECLARE_PRIVATE(Region)
};

Q_DECLARE_METATYPE(Region*)

inline QDataStream& 
	operator<<(QDataStream &archive, const Region &item)
{		
	return item.operator<<(archive);
}

inline QDataStream& 
	operator<<(QDataStream &archive, const Region *item)
{	
	return operator<<(archive, *item);		
}

inline QDataStream& 
	operator>>(QDataStream &archive, Region &item)
{
	return item.operator>>(archive);
	return archive;
}

inline QDataStream& 
	operator>>(QDataStream &archive, Region *item)
{		
	return operator>>(archive,*item);
}

class RectanglePrivate;
class Rectangle : public Region
{
public:
	Rectangle(Region *parent = 0);
	Rectangle(const QSizeF& size, Region *parent = 0);
	~Rectangle();		
public:
	virtual void paint(QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget = 0);		
	virtual Region* clone() const;	
	virtual QPainterPath shape() const;
	virtual bool contains(const QPointF& pos) const;
	virtual int type() const {return RectangleType;}
protected:
	Rectangle(RectanglePrivate &dd, 
		Region *parent = 0, 
		RegionScene* scene = 0);	
protected:
	virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *);
	virtual void wheelEvent(QGraphicsSceneWheelEvent *);
	virtual void hoverEnterEvent(QGraphicsSceneHoverEvent *);
private:
	Q_DISABLE_COPY(Rectangle)
	Q_DECLARE_PRIVATE(Rectangle)
};

class EllipsePrivate;
class Ellipse : public Rectangle
{

public:
	Ellipse(Region *parent = 0);
	Ellipse(const QSizeF& size, Region *parent = 0);
	~Ellipse();
protected:
	Ellipse(EllipsePrivate &dd, 
		Region *parent = 0, 
		RegionScene *scene = 0);	
public:
	virtual QPainterPath shape() const;
	virtual void paint(QPainter * painter, 
		const QStyleOptionGraphicsItem * option, 
		QWidget * widget = 0);
	virtual int type() const {return EllipseType;}
private:
	Q_DISABLE_COPY(Ellipse)
	Q_DECLARE_PRIVATE(Ellipse)
};

class RingPrivate;
class Ring : public Region
{

public:
	Ring(Region *parent = 0);
	Ring(const QSizeF& rectangleSize, const QSizeF& ringSize, Region *parent = 0);
	~Ring();
public:
	QSizeF ringSize() const;
	void setRingSize(const QSizeF&);
public:
	virtual void paint(QPainter * painter, 
		const QStyleOptionGraphicsItem * option, 
		QWidget * widget = 0) = 0;	
protected:
	Ring(RingPrivate &dd, 
		Region *parent = 0, 
		RegionScene* scene = 0);	
protected:
	virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *);
	virtual void mousePressEvent(QGraphicsSceneMouseEvent *);
	virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *);
	virtual void wheelEvent(QGraphicsSceneWheelEvent *);
	virtual void hoverEnterEvent(QGraphicsSceneHoverEvent *);
private:
	Q_DISABLE_COPY(Ring)
	Q_DECLARE_PRIVATE(Ring)
};

class RectangleRing : public Ring
{

public:
	RectangleRing(Region *parent = 0);
	RectangleRing(const QSizeF& rectangleSize, const QSizeF& ringSize, Region *parent = 0);
	~RectangleRing();
protected:

public:
	virtual void paint(QPainter * painter, 
		const QStyleOptionGraphicsItem * option, 
		QWidget * widget = 0);
	virtual int type() const {return RectangleRingType;}
};

class EllipseRing : public Ring
{

public:
	EllipseRing(Region *parent = 0);
	EllipseRing(const QSizeF& rectangleSize, 
		const QSizeF& ringSize, 
		Region *parent = 0);
	~EllipseRing();
public:
	virtual void paint(QPainter * painter, 
		const QStyleOptionGraphicsItem * option, 
		QWidget * widget = 0);
	virtual int type() const {return EllipseRingType;}
};	

class PolygonItemPrivate;
class PolygonItem : public Region
{

public:
	PolygonItem(Region *parent = 0);
	PolygonItem(const QPolygonF& polygon, Region *parent = 0);
	~PolygonItem();
public:
	QPolygonF polygon() const;
	QPolygonF& refPolygon();
	void setPolygon(const QPolygonF& polygon);	
public:
	virtual Region* clone() const;
	virtual void paint(QPainter *painter, 
		const QStyleOptionGraphicsItem *option, 
		QWidget *widget);	
	virtual QImage grabImage(const QImage&) const;
	virtual QImage excludeImage(const QImage& ,
		const QPointF& imageOrgin = QPointF(0.,0.), 
		const QColor& fillColor = Qt::black) const;
	virtual QPainterPath shape() const;
	virtual int type() const {return PolygonType;}
protected:
	virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *);
	virtual void mousePressEvent(QGraphicsSceneMouseEvent *);
	virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *);
	virtual void wheelEvent(QGraphicsSceneWheelEvent *);
private:
	Q_DISABLE_COPY(PolygonItem)
	Q_DECLARE_PRIVATE(PolygonItem)
};

class RegionGroup : public Rectangle
{

public:
	RegionGroup(Region *parent = 0);
	~RegionGroup();
public:
	void addToGroup(Region* item);
	void removeFromGroup(Region * item);	
public:
	virtual Region* clone() const;	
	virtual QPainterPath shape() const;
	virtual void paint(QPainter * painter, 
		const QStyleOptionGraphicsItem * option, 
		QWidget * widget = 0);
	virtual int type() const {return GroupType;}
private:
	Q_DISABLE_COPY(RegionGroup)
};

#endif // REGIONITEM_H
